﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using MathNet.Numerics.LinearAlgebra.Single;
using System.Collections;

namespace Pascal
{
    class Agent
    {
        private Point _location;  //present location of agent
        private static Random ranNum = new Random();

        public Point location //getter and setters
        {
            get { return this._location; }
            set { this._location = value; }
        }
        public Agent(Point position, ArrayList verts)
        {
            Object[] points = verts.ToArray();
            _location = position;
            moveTo((Point)points[ranNum.Next(verts.Count)]);
        }

        //constructor assigns a random location to agents within given dimension
        public Agent(Size window, Point A, Point B, Point C)
        {   
            _location.X = ranNum.Next(window.Width);
            _location.Y = ranNum.Next(window.Height);

            //make sure random point is outside main triangle.
            while (isInside(A, B, C))
            {
                _location.X = ranNum.Next(window.Width);
                _location.Y = ranNum.Next(window.Height);
            }
        }
        //tells agent to move half way to the given position
        public void moveTo(Point position)
        {
            _location.X = (_location.X + position.X ) / 2;
            _location.Y = (_location.Y + position.Y ) / 2;
        }
        //checks to see whether or not the agent is inside the area contained by the given three points.
        public bool isInside(Point A, Point B, Point C)
        {
            // first we create three vectors for two sides of the triangle and the agents position in relation to point A
            Single[] side0 = {C.X-A.X, C.Y - A.Y}, 
                side1 = {B.X-A.X, B.Y - A.Y},
                side2 = {_location.X-A.X, _location.Y - A.Y};
            DenseVector v0= new DenseVector(side0), 
                v1 = new DenseVector(side1), 
                v2 = new DenseVector(side2);
            //now we compute their dot products
            Single dot00 = v0.DotProduct(v0),
                dot01 = v0.DotProduct(v1),
                dot02 = v0.DotProduct(v2),
                dot11 = v1.DotProduct(v1),
                dot12 = v1.DotProduct(v2);
            // Compute barycentric coordinates
            Single invDenom = 1 / (dot00 * dot11 - dot01 * dot01),
                u = (dot11 * dot02 - dot01 * dot12) * invDenom,
                v = (dot00 * dot12 - dot01 * dot02) * invDenom;

            // Check if point is in triangle
            return (u >= 0) && (v >= 0) && (u + v < 1);
        }
    }
}
